package Practicas.practica2;

import data.IntegerDataSetGenerator;
import impl.BubbleSorter;
import impl.InsertionSorter;
import impl.SelectionSorter;
import test.BenchMark;

import java.util.ArrayList;
import java.util.Collections;


public class TestSorters {


    private ArrayList<Integer> list;

    private void testBubble(int valor) {
        list = new ArrayList<Integer>(valor);
        IntegerDataSetGenerator integerDataSetGenerator = new IntegerDataSetGenerator();
        BubbleSorter bubbleSorter = new BubbleSorter();
        float ascending, descending, random;
        ascending = descending = random = 0;
        BenchMark benchMark = new BenchMark();
        bubbleSorter.addSorterListener(benchMark);

        int swapsRandom, swapsAssendig, swapsDissendig, comparacionesRandom, comparacionesAssending, comparacionesDissending;
        swapsAssendig = swapsDissendig = swapsRandom = comparacionesRandom = comparacionesDissending = comparacionesAssending = 0;

        for (int i = 0; i < 3; i++) {
            list.removeAll(list);
            benchMark.resetAll();
            switch (i) {
                case 0:
                    list = (ArrayList<Integer>) integerDataSetGenerator.createAscending(valor);
                    long tiempoAs1 = System.currentTimeMillis();
                    bubbleSorter.sort(integerDataSetGenerator.getComparator(), list);
                    long tiempoAs2 = System.currentTimeMillis();
                    ascending = tiempoAs2 - tiempoAs1;
                    swapsAssendig = benchMark.getnSwap();
                    comparacionesAssending = benchMark.getComparations();
                    break;
                case 1:
                    list = (ArrayList<Integer>) integerDataSetGenerator.createAscending(valor);
                    Collections.shuffle(list);
                    long tiempoRan1 = System.currentTimeMillis();
                    bubbleSorter.sort(integerDataSetGenerator.getComparator(), list);
                    long tiempoRan2 = System.currentTimeMillis();
                    random = tiempoRan2 - tiempoRan1;
                    swapsRandom = benchMark.getnSwap();
                    comparacionesRandom = benchMark.getComparations();
                    break;
                case 2:
                    list = (ArrayList<Integer>) integerDataSetGenerator.createDescending(valor);
                    long tiempoDes1 = System.currentTimeMillis();
                    bubbleSorter.sort(integerDataSetGenerator.getComparator(), list);
                    long tiempoDes2 = System.currentTimeMillis();
                    descending = tiempoDes2 - tiempoDes1;
                    swapsDissendig = benchMark.getnSwap();
                    comparacionesDissending = benchMark.getComparations();
                    break;
            }
        }

        System.out.println("Bubble: " + "||Cant: " + valor);
        System.out.println("||Ascending: " + ascending + "||Swaps: " + swapsAssendig + "||Comparaciones: " + comparacionesAssending + "||");
        System.out.println("||Random: " + random + "||Swaps: " + swapsRandom + "||Comparaciones: " + comparacionesRandom + "||");
        System.out.println("||Discending: " + descending + "||Swaps: " + swapsDissendig + "||Comparaciones: " + comparacionesDissending + "||");
        System.out.println("");
    }

    private void testInsertion(int valor) {
        list = new ArrayList<Integer>(valor);
        IntegerDataSetGenerator integerDataSetGenerator = new IntegerDataSetGenerator();
        InsertionSorter insertionSorter = new InsertionSorter();
        float ascending, descending, random;
        ascending = descending = random = 0;
        BenchMark benchMark = new BenchMark();
        insertionSorter.addSorterListener(benchMark);

        int swapsRandom, swapsAssendig, swapsDissendig, comparacionesRandom, comparacionesAssending, comparacionesDissending;
        swapsAssendig = swapsDissendig = swapsRandom = comparacionesRandom = comparacionesDissending = comparacionesAssending = 0;

        for (int i = 0; i < 3; i++) {
            list.removeAll(list);
            switch (i) {
                case 0:
                    list = (ArrayList<Integer>) integerDataSetGenerator.createAscending(valor);
                    long tiempoAs1 = System.nanoTime();
                    insertionSorter.sort(integerDataSetGenerator.getComparator(), list);
                    long tiempoAs2 = System.nanoTime();
                    ascending = tiempoAs2 - tiempoAs1;
                    swapsAssendig = benchMark.getnSwap();
                    comparacionesAssending = benchMark.getComparations();
                    break;
                case 1:
                    list = (ArrayList<Integer>) integerDataSetGenerator.createAscending(valor);
                    Collections.shuffle(list);
                    long tiempoRan1 = System.nanoTime();
                    insertionSorter.sort(integerDataSetGenerator.getComparator(), list);
                    long tiempoRan2 = System.nanoTime();
                    random = tiempoRan2 - tiempoRan1;
                    swapsRandom = benchMark.getnSwap();
                    comparacionesRandom = benchMark.getComparations();
                    break;
                case 2:
                    list = (ArrayList<Integer>) integerDataSetGenerator.createDescending(valor);
                    long tiempoDes1 = System.nanoTime();
                    insertionSorter.sort(integerDataSetGenerator.getComparator(), list);
                    long tiempoDes2 = System.nanoTime();
                    descending = tiempoDes2 - tiempoDes1;
                    swapsDissendig = benchMark.getnSwap();
                    comparacionesDissending = benchMark.getComparations();
                    break;
            }
        }

        System.out.println("Insertion: " + "||Cant: " + valor);
        System.out.println("||Ascending: " + ascending + "||Swaps: " + swapsAssendig + "||Comparaciones: " + comparacionesAssending + "||");
        System.out.println("||Random: " + random + "||Swaps: " + swapsRandom + "||Comparaciones: " + comparacionesRandom + "||");
        System.out.println("||Discending: " + descending + "||Swaps: " + swapsDissendig + "||Comparaciones: " + comparacionesDissending + "||");
        System.out.println("");
    }

    private void testSelection(int valor) {
        list = new ArrayList<Integer>(valor);
        IntegerDataSetGenerator integerDataSetGenerator = new IntegerDataSetGenerator();
        SelectionSorter selectionSorter = new SelectionSorter();
        float ascending, descending, random;
        ascending = descending = random = 0;
        int swapsRandom, swapsAssendig, swapsDissendig, comparacionesRandom, comparacionesAssending, comparacionesDissending;
        swapsAssendig = swapsDissendig = swapsRandom = comparacionesRandom = comparacionesDissending = comparacionesAssending = 0;
        BenchMark benchMark = new BenchMark();
        selectionSorter.addSorterListener(benchMark);

        for (int i = 0; i < 3; i++) {
            list.removeAll(list);
            switch (i) {
                case 0:
                    list = (ArrayList<Integer>) integerDataSetGenerator.createAscending(valor);
                    long tiempoAs1 = System.nanoTime();
                    selectionSorter.sort(integerDataSetGenerator.getComparator(), list);
                    long tiempoAs2 = System.nanoTime();
                    ascending = tiempoAs2 - tiempoAs1;
                    swapsAssendig = benchMark.getnSwap();
                    comparacionesAssending = benchMark.getComparations();
                    break;
                case 1:
                    list = (ArrayList<Integer>) integerDataSetGenerator.createAscending(valor);
                    Collections.shuffle(list);
                    long tiempoRan1 = System.nanoTime();
                    selectionSorter.sort(integerDataSetGenerator.getComparator(), list);
                    long tiempoRan2 = System.nanoTime();
                    random = tiempoRan2 - tiempoRan1;
                    swapsRandom = benchMark.getnSwap();
                    comparacionesRandom = benchMark.getComparations();
                    break;
                case 2:
                    list = (ArrayList<Integer>) integerDataSetGenerator.createDescending(valor);
                    long tiempoDes1 = System.nanoTime();
                    selectionSorter.sort(integerDataSetGenerator.getComparator(), list);
                    long tiempoDes2 = System.nanoTime();
                    descending = tiempoDes2 - tiempoDes1;
                    swapsDissendig = benchMark.getnSwap();
                    comparacionesDissending = benchMark.getComparations();
                    break;
            }
        }

        System.out.println("Selection: " + "||Cant: " + valor);
        System.out.println("||Ascending: " + ascending + "||Swaps: " + swapsAssendig + "||Comparaciones: " + comparacionesAssending + "||");
        System.out.println("||Random: " + random + "||Swaps: " + swapsRandom + "||Comparaciones: " + comparacionesRandom + "||");
        System.out.println("||Discending: " + descending + "||Swaps: " + swapsDissendig + "||Comparaciones: " + comparacionesDissending + "||");
        System.out.println("");
    }


    public static void main(String[] args) {
        TestSorters ts = new TestSorters();
        int[] valores = {10, 50, 100, 250, 500, 1000, 2000, 3000, 4000, 5000};

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < valores.length; j++) {

                switch (i) {
                    case 0:
                        ts.testBubble(valores[j]);
                        break;
                    case 1:
                        ts.testInsertion(valores[j]);
                        break;
                    case 2:
                        ts.testSelection(valores[j]);
                        break;
                }

            }

        }
    }

}

